#ifndef __OBJ_HANDLER_H__
#define __OBJ_HANDLER_H__

#define BIG_STRING 4096


#include <stdio.h>
#include <math.h>

struct OBJvertex
{
	float x, y, z ;
	OBJvertex(float a, float b, float c){
		x = a; y = b; z = c;
	}
	OBJvertex(){
		x = y = z = 0.0;
	}
	void normalize(){
		float d = sqrtf(x*x+y*y+z*z);
		x/=d; y/=d; z/=d;
	}
	OBJvertex operator = (OBJvertex v){
		x = v.x; y = v.y; z = v.z;
		return (*this);
	}
	void operator +=(OBJvertex v){
		x += v.x; y += v.y; z+= v.z;
	}
	OBJvertex operator+(OBJvertex v){
		OBJvertex a = *this;
		a += v;
		return a;
	}
	void operator -=(OBJvertex v){
		x -= v.x; y -= v.y; z-= v.z;
	}
	OBJvertex operator-(OBJvertex a){
		OBJvertex v = *this;
		v -= a;
		return v;
	}
	OBJvertex operator*(float a){
		OBJvertex v = *this;
		v.x *= a; v.y *=a; v.z *=a;
		return v;
	}
	static float Dot(OBJvertex v1, OBJvertex v2){
		return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
	}
	static OBJvertex Cross(OBJvertex v1, OBJvertex v2){
		//v1.normalize(); 
		//v2.normalize();
		OBJvertex v3;
		v3.x = v1.y*v2.z - v1.z*v2.y;
		v3.y = v1.z*v2.x - v1.x*v2.z;
		v3.z = v1.x*v2.y - v1.y*v2.x;
		//v3.normalize();
		return v3;
	}
} ;

struct OBJmatrix
{
	// OBJmatrix Public Methods
	OBJmatrix() {
		for (int i = 0; i < 3; ++i)
			for (int j = 0; j < 3; ++j)
				if (i == j) m[i][j] = 1.;
				else m[i][j] = 0.;
	}
	OBJmatrix::OBJmatrix(float t00, float t01, float t02,
                     float t10, float t11, float t12,
                     float t20, float t21, float t22) {
		m[0][0] = t00; m[0][1] = t01; m[0][2] = t02;
		m[1][0] = t10; m[1][1] = t11; m[1][2] = t12;
		m[2][0] = t20; m[2][1] = t21; m[2][2] = t22;
	
	}
	float m[3][3];
};

struct OBJtexCoord
{
	float u, v ;
} ;

struct OBJtriangle
{
	int v1, v2, v3 ;
	int uv1, uv2, uv3 ;
} ;



class OBJHandler
{
public:
	OBJHandler() ;
	~OBJHandler() ;

	int LoadOBJascii(const char *fileName) ;
	int LoadOBJbin(const char *fileName) ;

	int SaveOBJascii(const char *fileName) ;
	int SaveOBJbin(const char *fileName) ;

	void OBJHandler::invTBNMatrix();

	OBJvertex   *verts ;
	OBJtexCoord *uvs   ;
	OBJtriangle *tris  ;

	OBJvertex	*normal;
	OBJvertex	*tangent;
	OBJvertex	*binormal;
	OBJmatrix	*TBN;

	int numVerts     ;
	int numTexCoords ;
	int numTris      ;
	int numNormals	;

	unsigned char hasTexCoords ;
	unsigned char hasNormals   ;

	void GatherASCIIInfo(FILE *fp) ;

	void Allocate(void) ;
	void DeAllocate(void) ;

	char *FetchLine(FILE *fp) ;
	int FetchWords(void) ;

	int EqualStrings(char *s1, char *s2) ;
	void GetIndices(char *word, int *vindex, int *tindex, int *nindex) ;


	char str[BIG_STRING];
	char str_orig[BIG_STRING];

	char **words;
	int max_words ;
	int num_words ;

} ;

#endif